/*
 * Copyright (C) 2012 Jesse Webb (gweebz@gmail.com)
 *
 * This file is part of Gwahtzee.
 *
 * Gwahtzee is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gwahtzee is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Gwahtzee.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.googlecode.gwahtzee;

import com.googlecode.gwahtzee.gui.Game;
import org.apache.commons.lang.SystemUtils;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.util.Log;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

public class Application {
    private static final String WINDOW_TITLE = "Gwahtzee";
    private static final int WINDOW_WIDTH = 1280;
    private static final int WINDOW_HEIGHT = 720;

    private static final String FULL_SCREEN_ARG = "-fullscreen";
    private static final String VERBOSE_ARG = "-verbose";

    private static final int FPS = 30;

    private static boolean fullscreen = false;
    private static boolean verbose = false;

    public static void main(String[] args) {
        addLwjglNativesToJavaLibraryPathProperty();

        Log.info("Launching Gwahtzee...");
        Log.info("Use " + FULL_SCREEN_ARG + " for full screen mode");
        Log.info("Use " + VERBOSE_ARG + " for verbose logging");

        if (args.length > 0) {
            List<String> argList = Arrays.asList(args);
            fullscreen = argList.contains(FULL_SCREEN_ARG);
            verbose = argList.contains(VERBOSE_ARG);
        }

        try {
            AppGameContainer gameContainer = new AppGameContainer(new Game(WINDOW_TITLE));
            gameContainer.setDisplayMode(WINDOW_WIDTH, WINDOW_HEIGHT, fullscreen);
            gameContainer.setIcons(new String[]{
                    "images/icon-16x16.png",
                    "images/icon-32x32.png",
                    "images/icon-64x64.png"
            });
            gameContainer.setTargetFrameRate(FPS);
            gameContainer.setVerbose(verbose);
            gameContainer.start();
        } catch (Exception e) {
            Log.error(e);
            System.exit(1);
        }

        Log.info("Exiting... good-bye!");
        System.exit(0);
    }

    private static void addLwjglNativesToJavaLibraryPathProperty() {
        String osDir;
        if (SystemUtils.IS_OS_WINDOWS) {
            osDir = "windows";
        } else if (SystemUtils.IS_OS_LINUX) {
            osDir = "linux";
        } else if (SystemUtils.IS_OS_MAC_OSX) {
            osDir = "macosx";
        } else if (SystemUtils.IS_OS_SOLARIS) {
            osDir = "solaris";
        } else {
            throw new RuntimeException("Unsupported OS: " + System.getProperty("os.name"));
        }
        addPathToJavaLibraryPathProperty("lib/natives/" + osDir);
    }

    // http://stackoverflow.com/q/5419039
    private static void addPathToJavaLibraryPathProperty(String propertyValue) {
        String propertyName = "java.library.path";
        try {
            Field field = ClassLoader.class.getDeclaredField("usr_paths");
            field.setAccessible(true);
            String[] paths = (String[]) field.get(null);
            for (String path : paths) {
                if (propertyValue.equals(path)) return;
            }
            String[] tmp = new String[paths.length + 1];
            System.arraycopy(paths, 0, tmp, 0, paths.length);
            tmp[paths.length] = propertyValue;
            field.set(null, tmp);
            System.setProperty(propertyName, System.getProperty(propertyName) + File.pathSeparator + propertyValue);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to get permissions to set " + propertyName);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException("Failed to get field handle to set " + propertyName);
        }
    }
}
